home *** CD-ROM | disk | FTP | other *** search
- #ifdef COMMENT
-
- | testATP.c
- |
- | This program scans the AppleTalk network for any specified AppleTalk servers
- | and displays them in a list. This is the Beta-test for a project which
- | I'm working on currently. I though it might be of interest to those
- | exploring the preferred AppleTalk interface, and entity structures.
- |
- | <c>1991 Mike Carter, MCDesign. You may use portions of this code if you like.
- | Bug reports and any (and all) comments are welcome! You can reach me via
- | E-Mail at CompuServe 76114,321.
- |
- | 'FindEntity' is an MCDesign original. All rights reserved.
- |
- | (Be sure to include AppleTalk, nAppleTalk, MacTraps & ANSI in your project)
-
- #endif
-
- #define SEARCH 1 /* Dialog items - main DLOG 129 */
- #define LIST 2
- #define NUMFOUND 3
- #define DONE 4
- #define LINE 6
- #define ICON 7
- #define MSG 8
- #define CHANGE 11
- #define ENTITY 12
- #define HELP 13
-
- #define LOOKING 1 /* Message strings */
- #define LOOKUPERR 2
- #define EXTRACTERR 3
- #define NO_DEVICES 4
- #define ALL_DONE 5
-
- #define OK 1 /* From set options DLOG 130 */
- #define CANCEL 2
- #define OBJ_ITEM 3
- #define TYPE_ITEM 4
- #define ZONE_ITEM 5
-
- #define BASE_RES 128
- #define NIL_POINTER 0L
- #define WNE_TRAP_NUM 0x60
- #define UNIMPL_TRAP_NUM 0x9F
-
- #include <nAppleTalk.h>
- #include <ListMgr.h>
- #include <string.h>
-
- typedef struct { /* this structure holds data on all found entities */
- Str32 eName; /* the entity's name */
- Str32 eType; /* the entity's type */
- int eNode; /* the Node -- in decimal form */
- int eSocket; /* the socket -- in decimal form */
- } response;
-
- void DrawTheLine( DialogPtr ); /* Draws a dotted line on a userItem */
- void DrawButton( DialogPtr ); /* outlines default button */
- void DoAlert( short ); /* Changes message area in DLOG */
- int findPrinters( response *, short * ); /* does all the ATP stuff */
- void doMyUpdate( Boolean ); /* updates DLOG */
- void Show_help( short, short, short, StringPtr, StringPtr );
-
-
- Str32 theObj = "\p="; /* Default settings for entity: */
- Str32 theType = "\pLaserWriter"; /* Any LaserWriter... */
- Str32 theZone = "\p*"; /* in our zone. */
- DialogPtr mainDlog, changeDlog;
- GrafPtr oldPort;
- short maxToGet = 25; /* max number to find */
- short numFound = 0; /* number found in search */
-
- ListHandle theListH;
- short totalCells = 0; /* keeps track of the number of cells in list */
- Boolean gDone = false;
- Boolean gWNElmplemented;
- EventRecord gTheEvent;
- Ptr theBuff, ePtr; /* NBP receive buffer; entity pointer */
- int buffSize; /* size of buffer */
- CursHandle WatchCursor;
- Str255 brag = "\pFindEntity <c>1991 MCDesign. Written by Mike Carter (76114,321) in Think C";
- response theResp[25]; /* See above */
-
-
- /******************************* main **********************************/
- main()
- {
- MaxApplZone(); /* get some ROOM!!!! */
- InitMac(); /* initialize Mac Managers */
-
- /* Allocate our main memory-gobbling structures first so */
- /* they end up at the bottom of our heap, causing much less */
- /* heap fragmentation. I call this semi-dynamic allocation! */
-
- buffSize = (sizeof( EntityName ) + 4) * maxToGet;
-
- theBuff = NewPtrClear( buffSize );
- if( theBuff == 0L )
- ExitToShell(); /* No memory!! */
-
- ePtr = NewPtrClear( 100 ); /* size for NBPSetEntity */
- if( ePtr == 0L )
- ExitToShell(); /* no memory!! */
-
- SetUpDlog(); /* load and show our main dialog */
-
- LoopTheLoop(); /* main event loop */
-
- /* clean-up routines */
- LDispose( theListH ); /* Can't say whether or not these */
- DisposPtr( ePtr ); /* are _really_ necessary, seeing */
- DisposPtr( theBuff ); /* that quitting the app. releases */
- DisposDialog( mainDlog ); /* it's memory anyway--but what the */
- HPurge((Handle)WatchCursor); /* heck! can't hurt!! */
-
- SetPort( oldPort ); /* Set the GrafPort back the way we found it */
-
- ExitToShell(); /* ta-ta for now */
- }
-
- /*********************** InitMac **************************/
- InitMac()
- {
- InitGraf( &thePort ); /* Initialize the Mac Managers */
- InitFonts();
- FlushEvents( everyEvent, 0 );
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs( 0L );
- InitCursor();
-
- WatchCursor=GetCursor( watchCursor ); /* standard wait cursor */
- HNoPurge((Handle)WatchCursor); /* keep it around a while */
- }
-
- /******************** SetUpDlog *****************************/
- SetUpDlog()
- {
- int type = 0, hit = 0;
- Rect box;
- Handle itemH;
-
- mainDlog = GetNewDialog( BASE_RES + 1, 0L, -1L ); /* Get our main Dialog */
- if( mainDlog == 0L )
- ExitToShell();
-
- GetPort( &oldPort ); /* Let's be port-friendly */
- SetPort( mainDlog );
-
- SetUpList(); /* define the list which shows the printer names */
-
- ShowWindow( mainDlog ); /* become visual reality */
- DrawDialog( mainDlog ); /* draw the guts */
-
- doMyUpdate( false ); /* draw outlines--but don't update list-it's non-extant */
- }
-
-
- /************************ SetUpList ********************************/
- SetUpList()
- {
- int type, i;
- Rect box, dataBounds, rView;
- Point cSize;
- Handle itemH;
- Cell theCell;
-
- GetDItem( mainDlog, LIST, &type, &itemH, &box );
-
- rView = box; /* Get rect size from our DITL user item */
- rView.left+=1; /* leave room for framerect */
- rView.right-=16; /* room for scroll bar and framerect */
- rView.bottom -= 1; /* room for framerect */
-
- cSize.h = rView.right - rView.left; /* set cell size */
- cSize.v = (rView.bottom - rView.top) / 6; /* show 6 cells at a time */
-
- SetRect(&dataBounds,0,0,1,0); /* one column, no cells - yet */
-
- theListH = LNew(&rView, &dataBounds, cSize, 0L, mainDlog, true, false, false, true);
- (**theListH).selFlags = lOnlyOne+lNoDisjoint+lNoExtend+lNoNilHilite;
-
- LActivate( false, theListH ); /* turn it off initially */
-
- }
-
- /**************************** LoopTheLoop ***************************/
- LoopTheLoop()
- {
-
- /* Is WaitNextEvent() implemented? If it is, the address of the
- * WaitNextEvent() trap will be different than the standard,
- * "unimplemented" trap...
- */
-
- gWNElmplemented = ( NGetTrapAddress( WNE_TRAP_NUM, ToolTrap ) !=
- NGetTrapAddress( UNIMPL_TRAP_NUM, ToolTrap ) );
-
- /*
- * Don't wait for a mouse click. Retrieve and process events
- * instead!
- */
-
- while ( gDone == false )
- {
- HandleEvent();
- }
- }
-
- /*************************** HandleEvent ****************************/
- HandleEvent()
- {
- int theItem, type;
- Handle itemH;
- Rect box;
- Point pt;
- int err = 0;
- long charCode, fake;
-
- if ( gWNElmplemented ) /* Use appropriate event routine */
- WaitNextEvent( everyEvent, &gTheEvent, 0L, 0L );
-
- else
- {
- SystemTask();
- GetNextEvent( everyEvent, &gTheEvent );
- }
-
- if (IsDialogEvent( &gTheEvent ) ) /* event happened inside the Dlog?? */
- {
- if ( DialogSelect( &gTheEvent, &mainDlog, &theItem ) ) /* yes it did!! */
- {
- switch( theItem )
- {
- case SEARCH: /* hit the search button */
- StartHere: /* for catching mouseDowns in the next switch */
- SetCursor(*WatchCursor);
-
- err = findPrinters( theResp, &numFound );
-
- LActivate( true, theListH ); /* activate the list */
- InitCursor(); /* cahnge back to arrow cursor */
- doMyUpdate( true );
-
- if( err != noErr)
- SysBeep( 30 );
- break;
-
- case DONE:
- gDone = true;
- return;
-
- case LIST:
- HandleListClick();
- break;
-
- case ICON:
- GetDItem( mainDlog, MSG, &type, &itemH, &box ); /* secret brag switch! */
- SetIText( itemH, &brag );
- break;
-
- case CHANGE:
- DoChange();
- doMyUpdate( true );
- break;
-
- case HELP:
- Show_help( 132, BASE_RES,1000, (StringPtr)"\pFindEntity Help",
- (StringPtr)"" );
- doMyUpdate( true );
- break;
-
- } /* switch theItem */
- gTheEvent.what = nullEvent; /* event handled-reset so next switch doesn't freak out */
-
- } /* DialogSelect */
-
- } /* IsDialogEvent */
-
-
-
- switch ( gTheEvent.what ) /* Okay, event wasn't part of dialog */
- {
- case nullEvent:
- break;
-
- case mouseDown: /* for drags and any stray DA windows */
- HandleMouseDown();
- break;
-
- case keyDown:
- charCode = BitAnd( gTheEvent.message, charCodeMask);
- if( (charCode == 13) || (charCode == 3) ) /* return or enter key */
- {
- GetDItem( mainDlog, SEARCH, &type, &itemH, &box );
- HiliteControl( itemH, 1 );
- Delay( 10, &fake ); /* do a fake button press hilite */
- HiliteControl( itemH, 0 );
- goto StartHere; /* same as click in Search button above */
- }
- else if( (charCode == '.') && (gTheEvent.modifiers & cmdKey) )
- {
- GetDItem( mainDlog, DONE, &type, &itemH, &box );
- HiliteControl( itemH, 1 );
- Delay( 10, &fake ); /* do a fake button press hilite */
- HiliteControl( itemH, 0 );
- gDone = true;
- return;
- }
- else if( (charCode == 'c') && (gTheEvent.modifiers & cmdKey) ) /* change button */
- {
- GetDItem( mainDlog, CHANGE, &type, &itemH, &box );
- HiliteControl( itemH, 1 );
- Delay( 10, &fake );
- HiliteControl( itemH, 0 );
- DoChange();
- doMyUpdate( true );
- }
- break;
-
- case updateEvt:
- BeginUpdate( gTheEvent.message );
- DrawDialog( mainDlog );
- doMyUpdate( true );
- EndUpdate( gTheEvent.message );
- break;
- } /* switch gTheEvent */
-
- } /* HandleEvent() */
-
-
- /**************************** HandleListClick **********************/
- HandleListClick()
- /* Handles clicks in the list of found entities. */
- {
- Point pt; /* location of the click */
- Cell aCell; /* cell where click occurred */
- Rect box; /* GetDItem stuff */
- Handle itemH; /* GetDItem stuff */
- int type; /* GetDItem stuff */
- char infoString[100]; /* standard C string (The hell w/Pascal!) */
- Str32 name; /* crummy pascal string */
-
- pt = gTheEvent.where; /* get mouseclick from the global eventRecord */
- GlobalToLocal( &pt ); /* the list needs in in local coords */
- LClick( pt, gTheEvent.modifiers, theListH ); /* handle the highlighting */
- *(long *)&aCell = LLastClick(theListH); /* find the cell last clicked in -- */
- /* the fancy footwork is a result of Think C */
- /* returning a long from the call to LLastClick */
- /* instead of a Cell--like pascal does. */
- if( aCell.v+1 <= numFound ) /* Test if user clicked in a valid cell */
- {
- BlockMove( (Ptr)&theResp[aCell.v+1].eType, &name, *theResp[aCell.v+1].eType+1 );
- PtoCstr( (char *)name );
- sprintf( infoString, "Type: %s, Node: %d, Socket: %d", name,
- (int)theResp[aCell.v+1].eNode, (int)theResp[aCell.v+1].eSocket );
- /** throw together a string--REAL C style!! */
- }
- else
- strcpy( infoString, "???" ); /* user clicked on an empty cell */
-
- CtoPstr( infoString ); /* convert our cool C string to a yucchy pascal string */
- GetDItem( mainDlog, MSG, &type, &itemH, &box );
- SetIText( itemH, infoString ); /* display the message */
- }
-
- /**************************** HandleMouseDown **********************/
- HandleMouseDown()
- {
- WindowPtr whichWindow;
- short int thePart;
- long windSize;
- GrafPtr oldPort;
- Rect dragRect = screenBits.bounds;
-
- /* First, find out which window the mouse click occurred in.
- * Then, find out what part of the window the mouse click occurred in.
- */
-
- thePart = FindWindow( gTheEvent.where, &whichWindow );
- switch ( thePart )
- {
- case inSysWindow : /* Probably a desk accessory window... */
- SystemClick( &gTheEvent, whichWindow );
- break;
-
- case inDrag: /* Drag the window around the screen, limited by dragRect */
- DragWindow( whichWindow, gTheEvent.where, &dragRect);
- DrawDialog( mainDlog );
- doMyUpdate( true ); /* update the screen */
- break;
- }
- }
-
-
- /***************************** DoChange *****************************/
- DoChange()
- /* Gets new search information for the next call to findPrinters */
- {
- GrafPtr oldPort;
- Boolean done = false;
- int type, itemHit;
- Handle objH, typeH, zoneH;
- Rect box;
- Str255 objStr, typeStr, zoneStr;
-
- GetPort( &oldPort );
- changeDlog = GetNewDialog( 130, 0L, -1L );
- SetPort( changeDlog );
-
- GetDItem( changeDlog, OBJ_ITEM, &type, &objH, &box ); /* get handles to editText items */
- GetDItem( changeDlog, TYPE_ITEM, &type, &typeH, &box );
- GetDItem( changeDlog, ZONE_ITEM, &type, &zoneH, &box );
- SetIText( objH, theObj ); /* set editText's to current search strings */
- SetIText( typeH, theType );
- SetIText( zoneH, theZone );
-
- SelIText( changeDlog, OBJ_ITEM, 0, 32767); /* select first editText's text */
-
- ShowWindow( changeDlog ); /* make sure we're seen */
- DrawDialog( changeDlog );
-
- while( !done )
- {
- ModalDialog( NIL_POINTER, &itemHit ); /* do a modal Dialog */
- switch( itemHit )
- {
- case CANCEL:
- done = true;
- break;
-
- case OK: /* okay, copy new settings to global strings */
- GetIText( objH, &objStr );
- if( objStr[0] > 0 ) /* check for empty editText string */
- {
- theObj[0] = '\0';
- BlockMove( objStr, theObj, (Size) objStr[0] + 1 );
- }
-
- GetIText( typeH, &typeStr );
- if( typeStr[0] > 0 ) /* check for empty editText string */
- {
- theType[0] = '\0';
- BlockMove( typeStr, theType, (Size) typeStr[0] + 1 );
- }
-
- GetIText( zoneH, &zoneStr );
- if( zoneStr[0] > 0 ) /* check for empty editText string */
- {
- theZone[0] = '\0';
- BlockMove( zoneStr, theZone, (Size) zoneStr[0] + 1 );
- }
-
- done = true;
- break;
- }
- }
- HideWindow( changeDlog );
- DisposDialog( changeDlog ); /* free up some mem-o-ry */
- SetPort( oldPort );
- }
-
-
- /************************** findPrinters ****************************/
- int findPrinters( response *theResp, short *numFound)
- {
- EntityName aFoundPrinter; /* holds info for found printers */
- AddrBlock entityAddr; /* address for found printers */
- int type = 0, i = 0; /* Dlog stuff */
- long dummy; /* Delay() dummy var */
- Handle itemH; /* Dlog stuff */
- Rect box; /* ditto. */
- Str255 look, numStr; /* a mesage */
- MPPParamBlock p; /* preferred interface paramBlock */
- OSErr err; /* OS err value */
- Cell theCell; /* for the Dlog list */
- char message[100]; /* temp string for composing message */
-
- strcpy( message, "Looking for " ); /* Compose the Looking string */
- strncat( message, (char *)&theType[1], (int)*theType );
- strcat( message, "'s...");
- CtoPstr( message );
- GetDItem( mainDlog, MSG, &type, &itemH, &box );
- SetIText( itemH, &message );
-
- NBPSetEntity( ePtr, theObj, theType, theZone ); /* setup up the entity */
-
- p.ioCompletion = 0L; /* no completion procedure */
- p.NBPinterval = 2; /* interval of two */
- p.NBPcount = 3; /* retry three times only */
- p.NBPentityPtr = ePtr; /* the entity info */
- p.NBPretBuffPtr = theBuff; /* return buffer */
- p.NBPretBuffSize = buffSize;
- p.NBPmaxToGet = maxToGet; /* maximum entities to find */
-
- err = PLookupName( &p, false ); /* go lookin' */
- if( err != noErr )
- {
- DoAlert( LOOKUPERR ); /* ATalk error */
- return( -1 );
- }
-
- *numFound = p.NBPnumGotten; /* copy results */
-
- NumToString( p.NBPnumGotten, &numStr ); /* change numFound to a */
- GetDItem( mainDlog, NUMFOUND, &type, &itemH, &box ); /* string for display in */
- SetIText( itemH, &numStr ); /* the dialog box */
-
- if( p.NBPnumGotten <= 0 ) /* none found! */
- {
- if( totalCells < *numFound )
- LAddRow( *numFound - totalCells, totalCells, theListH );
- if( totalCells > *numFound )
- LDelRow( totalCells - *numFound, *numFound, theListH );
- totalCells = *numFound;
- DoAlert( NO_DEVICES ); /* return error code for none found */
- return( -1 );
- }
-
- if( totalCells < *numFound )
- LAddRow( *numFound - totalCells, totalCells, theListH );
- if( totalCells > *numFound )
- LDelRow( totalCells - *numFound, *numFound, theListH );
-
- theCell.h = 0; /* we're only using one column, so .h remains 0 */
-
- for( i = 1; i <= p.NBPnumGotten; i++ ) /* cycle thru and extract */
- {
- err = NBPExtract( theBuff, p.NBPnumGotten, i, &aFoundPrinter, &entityAddr );
- if( err != noErr )
- {
- DoAlert( EXTRACTERR );
- return( -1 );
- }
-
- /* Now move the info of the found printer at index 'i' to the string array */
- /* theResp, then copy the name to a cell in our list, finally make sure the */
- /* cell gets drawn. */
- BlockMove( (Ptr)&aFoundPrinter.objStr, (Ptr)&theResp->eName[i], *aFoundPrinter.objStr );
- theResp[i].eNode = entityAddr.aNode;
- theResp[i].eSocket = entityAddr.aSocket;
- BlockMove( (Ptr)&aFoundPrinter.typeStr, (Ptr)&theResp[i].eType,
- *aFoundPrinter.typeStr+1 );
- theCell.v = i - 1; /* go to next cell */
- LSetCell( (Ptr)&aFoundPrinter.objStr[1], aFoundPrinter.objStr[0],
- theCell, theListH );
- LDraw( theCell, theListH );
- }
-
- GetDItem( mainDlog, MSG, &type, &itemH, &box );
- SetIText( itemH, "\pAll done!!" );
-
- totalCells = *numFound; /* update our number 'o cells counter */
-
- return( 0 ); /* all is well */
- }
-
- /*************************** DoAlert ***************************/
- void DoAlert( short index )
- {
- int type;
- Rect box;
- Handle itemH;
- Str255 errStr;
-
- GetDItem( mainDlog, MSG, &type, &itemH, &box ); /* statText item */
- GetIndString( &errStr, BASE_RES, index );
-
- SetIText( itemH, &errStr );
- }
-
- /**************************** doMyUpdate ***************************/
- void doMyUpdate( Boolean includeList )
- /* Handles all screen updates */
- {
- DrawDialog( mainDlog );
- DrawTheLine( mainDlog );
- DrawButton( mainDlog );
- SetCurEntity();
- FrameListRect();
- if( includeList == true )
- LUpdate( (RgnHandle)(**theListH).port->visRgn, theListH );
- }
-
-
- /**************************** FrameListRect **************************/
- FrameListRect()
- {
- int type;
- Rect box;
- Handle itemH;
-
- GetDItem( mainDlog, LIST, &type, &itemH, &box );
- box.top -= 1;
- FrameRect( &box );
-
- DisposHandle( itemH );
- }
-
-
- /************************ SetCurEntity *************************/
- SetCurEntity()
- /* updates the curent search pattern shown on the main dialog */
- {
- int type, nextLine;
- FontInfo finfo;
- Handle itemH;
- Rect box;
-
- GetDItem( mainDlog, ENTITY, &type, &itemH, &box );
- FillRect( &box, white );
-
- ForeColor( redColor );
-
- TextFont( helvetica );
- GetFontInfo( &finfo );
- nextLine = finfo.ascent + finfo.descent + finfo.leading;
-
- MoveTo( box.left + 8, box.top + nextLine );
-
- DrawString( "\pObject: " );
- DrawString( theObj );
- MoveTo( box.left + 8, box.top + (2 * nextLine) );
-
- DrawString( "\pType: " );
- DrawString( theType );
- MoveTo( box.left + 8, box.top + (3 * nextLine) );
-
- DrawString( "\pZone: " );
- DrawString( theZone );
-
- }
-
-
- /************************* DrawTheLine *************************/
- void DrawTheLine( DialogPtr theDlog )
- /*
- | This function will, utilizing the Rect defined in the user item
- | within the rez file, draw a dotted line to seperate the message
- | line at the bottom of the DLOG from the parts above it.
- */
- {
- Handle itemH;
- Rect box, theRect;
- Point where, left, right;
- int type;
-
- GetDItem( theDlog, LINE, &type, &itemH, &box );
-
- PenPat( ltGray );
- PenSize( 1, 1 );
-
- MoveTo( box.left, box.top );
- LineTo( box.right, box.top );
-
- PenNormal();
- }
-
- /*************************** DrawButton ************************/
- void DrawButton( theDialog )
- DialogPtr theDialog;
- /* Outlines the default button--actually, I just discovered I can use */
- /* a CDEV resource and CNTL resource in my rez file to do the same thing!! */
- /* (it's done that way for the help dialog) */
- {
- int itemType;
- Rect itemRect;
- Handle item;
- GrafPtr oldPort;
-
- GetPort( &oldPort );
- GetDItem( theDialog, SEARCH, &itemType, &item, &itemRect );
- SetPort( theDialog );
-
- PenSize( 3,3 );
- InsetRect( &itemRect, -4, -4 );
- FrameRoundRect( &itemRect, 16, 16 );
- PenNormal();
-
- SetPort( oldPort );
- }
-